﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
using ReadyApps.Common;
using ReadyApps.Common.Exceptions;
using ReadyApps.Data;
using ReadyApps.Data.Wiki;
using ReadyApps.Wiki.Templates;

namespace ReadyApps.Wiki.Views
{
    class NormalView : ContentViewBase, IViewFiresTitleSetEvent
    {
        #region Variables and Constants

        private IWikiSecurityManager securityManager;
        private PageDetails pageDetails;

        #endregion

        #region Events

        private event EventHandler editButtonClick;
        public event EventHandler EditButtonClick
        {
            add { editButtonClick += value; }
            remove { editButtonClick -= value; }
        }

        private event EventHandler settingsButtonClick;
        public event EventHandler SettingsButtonClick
        {
            add { settingsButtonClick += value; }
            remove { settingsButtonClick -= value; }
        }

        private event EventHandler editPermissionsButtonClick;
        public event EventHandler EditPermissionsButtonClick
        {
            add { editPermissionsButtonClick += value; }
            remove { editPermissionsButtonClick -= value; }
        }

        private event EventHandler viewRevisionsButtonClick;
        public event EventHandler ViewRevisionsButtonClick
        {
            add { viewRevisionsButtonClick += value; }
            remove { viewRevisionsButtonClick -= value; }
        }

        private event EventHandler viewPendingButtonClick;
        public event EventHandler ViewPendingButtonClick
        {
            add { viewPendingButtonClick += value; }
            remove { viewPendingButtonClick -= value; }
        }

        private event EventHandler createPageButtonClick;
        public event EventHandler CreatePageButtonClick
        {
            add { createPageButtonClick += value; }
            remove { createPageButtonClick -= value; }
        }

        #endregion

        #region Constructor

        public NormalView(int pageID, PageDetails wikiPageDetails, WikiControlSettings wikiControlSettings,
            IWikiDataProvider wikiDataProvider, IWikiUrlManager wikiUrlManager, IWikiSecurityManager wikiSecurityManager)
            : base(pageID, wikiControlSettings, wikiDataProvider, wikiUrlManager)
        {
            TraceManager.BeginMethod(TraceComponent.NormalView, "Ctor");

            if (wikiSecurityManager == null)
            {
                throw new ArgumentNullException("wikiSecurityManager");
            }
            pageDetails = wikiPageDetails;
            securityManager = wikiSecurityManager;

            TraceManager.EndMethod(TraceComponent.NormalView, "Ctor");
        }

        #endregion

        #region Public Methods

        public override void BuildControlTree(ControlCollection controls, bool raiseEvents)
        {
            TraceManager.BeginMethod(TraceComponent.NormalView, "BuildControlTree");

            Control container = new Control();

            // Instantiate the template
            ITemplate layoutTemplate = controlSettings.LayoutTemplate ?? new WikiDefaultLayoutTemplate();
            layoutTemplate.InstantiateIn(container);

            // Locate the content and wiki controls control
            Control contentControl = WebUtilities.FindControlRecursive(container, WikiController.CONTENT_CONTROL_ID);
            if (contentControl == null)
            {
                throw new MissingControlException(WikiController.CONTENT_CONTROL_ID, location: "layout template");
            }
            Control controlsControl = WebUtilities.FindControlRecursive(container, WikiController.CONTROLS_CONTROL_ID);
            if (controlsControl == null)
            {
                throw new MissingControlException(WikiController.CONTROLS_CONTROL_ID, location: "layout template");
            }

            // Lookup the page info and add the controls for the content elements
            PageContent content = dataProvider.GetPageContent(pageID);
            GetContentControls(content, contentControl);

            // Display the wiki controls that the user has access to
            List<WikiControlButton> options = GetAvailableOptions();
            for (int i = 0; i < options.Count; i++)
            {
                if (i != 0)
                {
                    controlsControl.Controls.Add(new Literal() { Text = WikiController.BUTTON_SPACER });
                }
                controlsControl.Controls.Add(options[i].RootControl);
            }

            controls.Clear();
            controls.Add(container);

            if (raiseEvents)
            {
                controlSettings.OnTitleSet(this, new TitleSetEventArgs(content.Title));
            }

            TraceManager.EndMethod(TraceComponent.NormalView, "BuildControlTree");
        }

        #endregion

        #region Private Methods

        private List<WikiControlButton> GetAvailableOptions()
        {
            List<WikiControlButton> options = new List<WikiControlButton>(6);
            if (securityManager.CanCreatePage)
            {
                WikiControlButton createPage = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                createPage.ButtonControl.Text = "New Page";
                createPage.ButtonControl.Click += createPageButtonClick;
                options.Add(createPage);
            }
            if (securityManager.CanEditPermissions)
            {
                WikiControlButton editPermissions = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                editPermissions.ButtonControl.Text = "Permissions";
                editPermissions.ButtonControl.Click += editPermissionsButtonClick;
                options.Add(editPermissions);
            }
            if (securityManager.CanEditSettings)
            {
                WikiControlButton editSettings = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                editSettings.ButtonControl.Text = "Settings";
                editSettings.ButtonControl.Click += settingsButtonClick;
                options.Add(editSettings);
            }
            if (pageDetails.Versioned && securityManager.CanManageRevisions)
            {
                WikiControlButton manageRevisions = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                manageRevisions.ButtonControl.Text = "Revisions";
                manageRevisions.ButtonControl.Click += viewRevisionsButtonClick;
                options.Add(manageRevisions);
            }
            if (pageDetails.Publishable && pageDetails.PendingRevision &&
                (securityManager.CanManagePublishing || securityManager.IsSameUser(pageDetails.PendingRevisionAuthor)))
            {
                WikiControlButton viewPending = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                viewPending.ButtonControl.Text = "View Pending";
                viewPending.ButtonControl.Click += viewPendingButtonClick;
                options.Add(viewPending);
            }
            if (securityManager.CanEditPage && !(pageDetails.Publishable && pageDetails.PendingRevision))
            {
                WikiControlButton editPage = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                editPage.ButtonControl.Text = "Edit";
                editPage.ButtonControl.Click += editButtonClick;
                options.Add(editPage);
            }
            return options;
        }

        #endregion
    }
}
